package com.changgou.seckill.task;

import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.utill.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;

@Component
public class SeckillGoodsPushTask {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    public static final String SECKILL_GOODS_KEY="seckill_goods_";

    public static final String SECKILL_GOODS_STOCK_COUNT_KEY="seckill_goods_stock_count_";

    @Autowired
    private RedisTemplate redisTemplate;

    @Scheduled(cron ="0/30 * * * * ?")
    public void loadSeckKillGoodsToRedis(){
        System.out.println("定时任务开始执行");
        //获取以当前时间段开始的五个时间段
        List<Date> dateMenus = DateUtil.getDateMenus();
        //遍历每一个时间段
        for (Date dateMenu : dateMenus) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //将Date格式转换成字符串格式作为后续存储到redis中的键的
            String redisExtName = DateUtil.date2Str(dateMenu);

            //构建查询数据库的条件
            Example example=new Example(SeckillGoods.class);
            Example.Criteria criteria = example.createCriteria();
            //审核状态为已审核
            criteria.andEqualTo("status","1");
            //库存数量要大于0
            criteria.andGreaterThan("stockCount",0);
            //开始时间晚于当前时间段的开始节点
            criteria.andGreaterThanOrEqualTo("startTime",simpleDateFormat.format(dateMenu));
            //结束时间早于当前时间段的结束节点
            criteria.andLessThan("endTime",simpleDateFormat.format(DateUtil.addDateHour(dateMenu,2)));
            //在redis中是以hash的格式进行秒杀商品的存储,键为时间段,map的键为秒杀商品的id,值为获取redis中各时间段的秒杀商品
            //获取redis中map的键,即ids
            Set keys = redisTemplate.boundHashOps(SECKILL_GOODS_KEY + redisExtName).keys();
            if(keys!=null&&keys.size()>0){
                //在某一个时间段内,redis中如果包含了这个商品的秒杀信息,那么就不需要再查询出来了
                criteria.andNotIn("id",keys);
            }
            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectByExample(example);
            //循环遍历将所有查询出来的商品存储到redis中
            for (SeckillGoods seckillGoods : seckillGoodsList) {
                redisTemplate.opsForHash().put(SECKILL_GOODS_KEY + redisExtName, seckillGoods.getId(), seckillGoods);

                //预先加载秒杀商品的库存到redis
                redisTemplate.opsForValue().set(SECKILL_GOODS_STOCK_COUNT_KEY+seckillGoods.getId(),seckillGoods.getStockCount());
            }
            System.out.println("定时任务执行完毕");
        }
    }
}
